package com.sinochem.sales.workflow.controller;

import com.sinochem.sales.common.entity.Result;
import com.sinochem.sales.common.util.AssertUtils;
import com.sinochem.sales.common.util.UserUtils;
import com.sinochem.sales.workflow.entity.LeaveOpinion;
import com.sinochem.sales.workflow.entity.MyTask;
import com.sinochem.sales.workflow.entity.UserLeave;
import com.sinochem.sales.workflow.service.LeaveService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableUpdate;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.lang3.StringUtils;
import org.sagacity.sqltoy.model.PaginationModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author xuan😴🐶🐱🐽🌺  <a href="zhangshixuanj@163.com">联系作者</a>
 * @version Revision:v1.0,Date: 2018/5/2 9:30
 * @project parent
 * @description 请假流程示例
 * @Modification Date: 2018/5/4 9:30  {填写修改说明}
 */
@RestController
@RequestMapping("/leave")
public class LeaveController {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;

    @Resource
    private ProcessEngineFactoryBean processEngine;

    @Resource
    private LeaveService leaveService;

    @Autowired
    HistoryService historyService;

    @Autowired
    private ProcessEngineConfiguration processEngineConfiguration;

    private String leaveOpinionList = "leaveOpinionList";

    /*我的请假列表*/
    @GetMapping("showLeaveList")
    public Result<List<UserLeave>> showLeaveList(UserLeave userLeave, PaginationModel paginationModel) {
        String userId = UserUtils.getUID();
        userLeave.setUserId(userId);
        List<UserLeave> tList = null;
        try {
            tList = leaveService.findLeavePage(userLeave);
            for (UserLeave leave : tList) {
                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                        .processInstanceId(leave.getProcessInstanceId()).singleResult();
                //保证运行ing
                if (instance != null) {
                    Task task = this.taskService.createTaskQuery().processInstanceId(leave.getProcessInstanceId()).singleResult();
                    leave.setTaskName(task.getName());
                    leave.setTaskId(task.getId());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        List<UserLeave> currentPageData = new ArrayList<>();
        tList.stream().skip((paginationModel.getPageNo() - 1) * paginationModel.getPageNo()).limit(paginationModel.getPageNo()).forEach(e -> currentPageData.add(e));
        return Result.success(currentPageData);
    }

    /*执行对象id获取审批信息*/
    @GetMapping("leaveDetail")
    public Result<List<LeaveOpinion>> leaveDetail(String processId) {
        ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processId).singleResult();
        //保证运行ing
        List<LeaveOpinion> leaveList = null;
        List<HistoricActivityInstance> historicActivityInstanceList = new ArrayList<>();
        if (instance != null) {
            Task task = this.taskService.createTaskQuery().processInstanceId(processId).singleResult();
            Map<String, Object> variables = taskService.getVariables(task.getId());
            Object o = variables.get(leaveOpinionList);
            if (o != null) {
                /*获取历史审核信息*/
                leaveList = (List<LeaveOpinion>) o;
            }
        } else {
            leaveList = new ArrayList<>();
            List<HistoricDetail> list = historyService.createHistoricDetailQuery().
                    processInstanceId(processId).list();
            HistoricVariableUpdate variable = null;
            for (HistoricDetail historicDetail : list) {
                variable = (HistoricVariableUpdate) historicDetail;
                String variableName = variable.getVariableName();
                if (leaveOpinionList.equals(variable.getVariableName())) {
                    leaveList.clear();
                    leaveList.addAll((List<LeaveOpinion>) variable.getValue());
                }
            }
        }
        return Result.success(leaveList);
    }


    /*修改查询*/
    @GetMapping("getLeave/{taskId}")
    public Result<UserLeave> updateLeave(@PathVariable String taskId) {
        Map<String, Object> variables = taskService.getVariables(taskId);
        UserLeave leave = (UserLeave) variables.get("userLeave");
        leave = leaveService.findLeave(leave);
        return new Result<>(leave);
    }

    /*调整*/
    @PostMapping("updateLeave/updateLeave/{taskId}/{id}/{flag}")
    public Result<String> updateLeave(UserLeave leave, @PathVariable String taskId, @PathVariable String id, @PathVariable boolean flag) {
        try {
            UserLeave oldLeave = leaveService.findLeave(leave);
            BeanUtils.copyProperties(leave, oldLeave);
            leaveService.saveOrUpdate(oldLeave);
            Map<String, Object> variables = taskService.getVariables(taskId);
            UserLeave userLeave = (UserLeave) variables.get("userLeave");
            Map<String, Object> map = new HashMap<>();
            if (flag) {
                map.put("flag", true);
            } else {
                map.put("flag", false);
            }
            taskService.complete(taskId, map);
            return Result.success("保存成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("保存失败");
        }
    }

    /*添加*/
    @PostMapping("addLeave")
    public Result<String> addLeave(UserLeave userLeave) {
        AssertUtils.isBlank(userLeave.getReason(), "请假信息不能为空");
        userLeave.setDays(3);
        userLeave.setUserId(UserUtils.getUID());
        userLeave.setUserName(UserUtils.getUser());

        leaveService.saveOrUpdate(userLeave);
        Map<String, Object> variables = new HashMap<>();
        variables.put("userLeave", userLeave);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process_leave", variables);
        if (processInstance == null) {
            return Result.error("未识别key");
        }
        userLeave.setProcessInstanceId(processInstance.getId());
        UserLeave userLeave1 = leaveService.findLeave(userLeave);
        BeanUtils.copyProperties(userLeave, userLeave1);
        leaveService.saveOrUpdate(userLeave1);
        return Result.success("请假成功");
    }

    /*我的任务*/
    @GetMapping(value = "showTaskList")
    public Result<List<MyTask>> showTaskList(MyTask myTask, PaginationModel paginationModel) {
        List<org.activiti.engine.task.Task> taskList = taskService.createTaskQuery().taskCandidateUser(UserUtils.getUID()).list();
        List<MyTask> tasks = new ArrayList<>();
        Map<String, Object> map;
        MyTask taskEntity;
        Map<String, Object> objectMap;

        Map<String, Map<String, Object>> mapMap = new HashMap<>();
        for (org.activiti.engine.task.Task task1 : taskList) {
            objectMap = new HashMap<>();
            map = taskService.getVariables(task1.getId());
            UserLeave userLeave = (UserLeave) map.get("userLeave");

            taskEntity = new MyTask(task1);
            taskEntity.setUserName(userLeave.getUserName());
            taskEntity.setReason(userLeave.getReason());
            /**如果是自己*/
            /*if (user.getId().equals(userLeave.getUserId()) && !(boolean) map.get("flag")) {
                objectMap.put("flag", true);
            } else {
                objectMap.put("flag", false);
            }*/
            mapMap.put(taskEntity.getId(), objectMap);
            tasks.add(taskEntity);
        }
        return Result.success(tasks);
    }

    /*审批*/
    @PostMapping("agent/complete")
    public Result<String> complete(LeaveOpinion op, HttpServletRequest request) {
        Map<String, Object> variables = taskService.getVariables(op.getTaskId());
        UserLeave userLeave = (UserLeave) variables.get("userLeave");
        op.setCreateTime(new Date());
        op.setOpId(UserUtils.getUID());
        op.setOpName(UserUtils.getUser());
        Map<String, Object> map = new HashMap<>();
        map.put("flag", op.isFlag());
        //审批信息叠加
        List<LeaveOpinion> leaveList = new ArrayList<>();
        Object o = variables.get(leaveOpinionList);
        if (o != null) {
            leaveList = (List<LeaveOpinion>) o;
        }
        leaveList.add(op);
        map.put(leaveOpinionList, leaveList);
        taskService.complete(op.getTaskId(), map);
        return new Result<>("审核成功");
    }

    /**
     * 追踪图片成图
     *
     * @param request
     * @param resp
     * @param processInstanceId
     * @throws IOException
     */
    @GetMapping("getProcImage")
    public void getProcImage(HttpServletRequest request, HttpServletResponse resp, String processInstanceId)
            throws IOException {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        HistoricProcessInstance historicProcessInstance =
                historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String processDefinitionId = null;
        List<String> executedActivityIdList = new ArrayList<>();
        if (processInstance != null) {
            processDefinitionId = processInstance.getProcessDefinitionId();
            executedActivityIdList = this.runtimeService.getActiveActivityIds(processInstance.getId());
        } else if (historicProcessInstance != null) {
            processDefinitionId = historicProcessInstance.getProcessDefinitionId();
            List<HistoricActivityInstance> historicActivityInstanceList =
                    historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
                executedActivityIdList.add(activityInstance.getActivityId());
            }
        }

        if (StringUtils.isEmpty(processDefinitionId) || executedActivityIdList.isEmpty()) {
            return;
        }
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        //List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
        processEngineConfiguration = processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);
        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
        //List<String> activeIds = this.runtimeService.getActiveActivityIds(processInstance.getId());

        InputStream imageStream = diagramGenerator.generateDiagram(
                bpmnModel, "png",
                executedActivityIdList, Collections.<String>emptyList(),
                processEngine.getProcessEngineConfiguration().getActivityFontName(),
                processEngine.getProcessEngineConfiguration().getLabelFontName(),
                null, 1.0);
        byte[] b = new byte[1024];
        int len;
        while ((len = imageStream.read(b, 0, 1024)) != -1) {
            resp.getOutputStream().write(b, 0, len);
        }
    }

}
